package sicnu.cs.ich.security.security.provider;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import sicnu.cs.ich.api.domain.form.WechatUserForm;
import sicnu.cs.ich.security.exceptions.exception.WechatLoginException;
import sicnu.cs.ich.security.security.service.WechatUserServiceImpl;
import sicnu.cs.ich.security.security.token.WechatAuthenticationToken;

/**
 * @author 沈洋 邮箱:1845973183@qq.com
 * @create 2021/5/20-17:52
 **/
@Slf4j
@Component
public class WechatAuthenticationProvider implements AuthenticationProvider {
    private final WechatUserServiceImpl userDetailsService;
    public WechatAuthenticationProvider(WechatUserServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        WechatAuthenticationToken authenticationToken = (WechatAuthenticationToken) authentication;
        //从Token中获取到mobile，然后调用service方法进行认证
        UserDetails user = null;
        WechatUserForm userForm = (WechatUserForm) authenticationToken.getPrincipal();
        try {
            user = userDetailsService.loadUserByOpenId(userForm);
        } catch (WechatLoginException ex) {
            log.info("无法创建用户");
            throw ex;
        }
        //认证成功，构造一个新的具有用户信息的token
        WechatAuthenticationToken authenticationResult = new WechatAuthenticationToken(user, user.getAuthorities());
        authenticationResult.setDetails(authenticationToken.getDetails());
        return authenticationResult;
    }



    @Override
    public boolean supports(Class<?> authentication) {
        return WechatAuthenticationToken.class.isAssignableFrom(authentication);
    }

}
